//
//  AutoScView.swift
//  WCSwiftDev
//
//  Created by ISSUSER on 2024/6/28.
//

import UIKit

class AutoScView: UIView, UIScrollViewDelegate {

    // MARK: - 属性
    private var _pageDefaultColor: UIColor?
    private var _pageCurrentColor: UIColor?

    var isClickValid: Bool = false
    var isShowProductImageStyle: Bool = false
    var aryImage: [Any] = []
    var numNow: Int = 0
    var timer: Timer?
    var numTime: Int = 0

    // block
    var blockSliding: ((Int) -> Void)?
    var blockNum: ((Int) -> Void)?

    // MARK: - lazy
    var pageControlToBottom: CGFloat = 0.0 {
        didSet {
            pageControl.centerXBottom = XY(width / 2, height - pageControlToBottom)
        }
    }

    var pageDefaultColor: UIColor {
        get {
            if _pageDefaultColor == nil {
                _pageDefaultColor = COLOR_LINE
            }
            return _pageDefaultColor!
        }
        set {
            _pageDefaultColor = newValue
            pageControl.pageIndicatorTintColor = newValue
        }
    }

    var pageCurrentColor: UIColor? {
        get {
            if _pageCurrentColor == nil {
                _pageCurrentColor = COLOR_PRIMARY()
            }
            return _pageCurrentColor!
        }
        set {
            _pageCurrentColor = newValue
            pageControl.currentPageIndicatorTintColor = newValue
        }
    }

    lazy var scView: UIScrollView = {
        let result = UIScrollView()
        result.widthHeight = XY(self.width, self.height)
        result.leftTop = XY(0, 0)
        result.delegate = self
        result.isPagingEnabled = true
        result.showsHorizontalScrollIndicator = false
        result.showsVerticalScrollIndicator = false
        result.backgroundColor = .clear
        result.bounces = false
        result.contentSize = CGSizeMake(CGRectGetWidth(self.frame) * 3, 0)
        return result
    }()

    // UIPageControl
    lazy var pageControl: CustomPageControl = {
        let result = CustomPageControl()
        result.widthHeight = XY(self.width, W(30))
        result.leftTop = XY(0, 0)
        result.currentPage = 0
        result.backgroundColor = .clear
        return result
    }()

    // MARK: - 初始化
    override init(frame: CGRect) {
        super.init(frame: frame)
        addSuview()
    }

    init(frame: CGRect, aryImage: [String]) {
        super.init(frame: frame)
        addSuview()
        resetView(imageAry: aryImage)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        addSuview()
    }

    func addSuview() {
        backgroundColor = COLOR_WHITE()
        isClickValid = true

        addSubview(scView)
        addSubview(pageControl)
    }

    // MARK: - 刷新View
    func resetView(imageAry aryImage: [Any]) {
        self.aryImage = aryImage
        scView.widthHeight = XY(width, height)
        scView.contentSize = CGSizeMake(CGRectGetWidth(frame) * 3, 0)
        // reset control
        pageControl.currentPageIndicatorTintColor = pageCurrentColor
        pageControl.pageIndicatorTintColor = pageDefaultColor
        pageControl.numberOfPages = self.aryImage.count
        pageControl.isHidden = pageControl.numberOfPages <= 1
        pageControl.width = width
        pageControl.centerXBottom = XY(width / 2.0, height - pageControlToBottom)
        pageControl.sizeToFit()
        pageControl.left = 20
        resetImageAnimated(false)
    }

    // 重置image
    func resetImageAnimated(_ animated: Bool) {
        guard aryImage.count > 0 else { return }
        scView.removeAllSubviews()
        numNow = (numNow < 0) ? (numNow + aryImage.count) : numNow
        let numTmp: Int = (numNow - 1 < 0) ? (aryImage.count - 1 + numNow) : numNow - 1
        let numFirst = numTmp % aryImage.count
        let numSec = numNow % aryImage.count
        let numThird = (numNow + 1) % aryImage.count

        addImage(numFirst, index: 0)
        addImage(numSec, index: 1)
        addImage(numThird, index: 2)

        if animated {
            startScrollAnimation()
        } else {
            scView.setContentOffset(CGPointMake(CGRectGetWidth(frame), 0), animated: false)
            pageControl.currentPage = numSec
        }

        // 滑动
        if let block = blockSliding {
            block(numSec)
        }
    }

    func addImage(_ num: Int, index: Int) {
        guard aryImage.count > num else { return }

        let iv = UIImageView()
        iv.widthHeight = XY(CGRectGetWidth(frame), CGRectGetHeight(frame))
        iv.leftTop = XY(CGFloat(index) * CGRectGetWidth(frame), 0)
        iv.backgroundColor = .clear
        iv.contentMode = .scaleAspectFill
        iv.clipsToBounds = true
        iv.isUserInteractionEnabled = true
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(imageClick(_:)))
        iv.addGestureRecognizer(tapGesture)

        let item = aryImage[num]
        if let imageView = item as? UIImageView {
            // 直接添加 UIImageView 作为子视图
            imageView.frame = iv.bounds
            imageView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            iv.addSubview(imageView)
        } else if let imageName = item as? String {
            iv.image = UIImage(named: imageName)
            if iv.image == nil {
                if isShowProductImageStyle {
                    iv.setImage(urlStr: imageName, "icon-ad-default")
                } else {
                    iv.setImage(urlStr: imageName, "icon-ad-default")
                }
            }
        }
        
        scView.addSubview(iv)
    }

    // MARK: - 点击事件
    @objc func imageClick(_ tap: UITapGestureRecognizer) {
        if !isAry(aryImage) {
            return
        }
        if !isClickValid {
            return
        }
        if tap.view is UIImageView {
            let numSec = numNow % aryImage.count
            print(" --- 图片点击 --- \(numSec)")
            if let block = blockNum {
                block(numSec)
            }
        }
    }

    // MARK: - ScrollView Delegate
    func scrollViewDidEndDecelerating(_: UIScrollView) {
        countNum()
    }

    func scrollViewDidEndDragging(_: UIScrollView, willDecelerate decelerate: Bool) {
        if !decelerate {
            countNum()
        }
    }

    func scrollViewDidEndScrollingAnimation(_: UIScrollView) {
        numNow += 1
        resetImageAnimated(false)
    }

    // MARK: - 重新计算
    func countNum() {
        numTime = 1
        if scView.contentOffset.x <= 5 {
            numNow -= 1
            resetImageAnimated(false)
        }
        if scView.contentOffset.x >= (CGRectGetWidth(frame) * 2 - 5) {
            numNow += 1
            resetImageAnimated(false)
        }
    }

    // MARK: - 计时器相关
    func timerStart() {
        // 开始计时器
        if timer == nil {
            timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(timerRun), userInfo: nil, repeats: true)
        }
        numTime = 0
    }

    @objc func timerRun() {
        // 每秒的动作
        if numTime > 0 {
            // 有人触碰 时间重置
            numTime = numTime - 1
            return
        }

        // 使用displayLink来创建平滑动画
        startScrollAnimation()
    }

    // 添加新属性
    private var displayLink: CADisplayLink?
    private var animationProgress: CGFloat = 0
    private var animationDuration: CFTimeInterval = 0.5
    private var animationStartTime: CFTimeInterval = 0

    // 添加新方法
    private func startScrollAnimation() {
        // 停止之前的动画（如果有）
        stopScrollAnimation()

        animationProgress = 0
        animationStartTime = CACurrentMediaTime()

        displayLink = CADisplayLink(target: self, selector: #selector(handleDisplayLink(_:)))
        displayLink?.add(to: .main, forMode: .common)
    }

    private func stopScrollAnimation() {
        displayLink?.invalidate()
        displayLink = nil
    }

    @objc private func handleDisplayLink(_: CADisplayLink) {
        let elapsed = CACurrentMediaTime() - animationStartTime
        let progress = min(elapsed / animationDuration, 1.0)

        // 使用 easeInOut 缓动函数
        let easedProgress = progress < 0.5
            ? 4 * progress * progress * progress
            : 1 - pow(-2 * progress + 2, 3) / 2

        let startX = CGRectGetWidth(frame)
        let endX = CGRectGetWidth(frame) * 2
        let currentX = startX + (endX - startX) * CGFloat(easedProgress)

        scView.setContentOffset(CGPointMake(currentX, 0), animated: false)

        if progress >= 1.0 {
            stopScrollAnimation()
            scrollViewDidEndScrollingAnimation(scView)
        }
    }

    // 停止计时器
    func timerStop() {
        if let timer = timer {
            timer.invalidate()
            self.timer = nil
        }
    }

    deinit {
        stopScrollAnimation()
        timerStop()
    }

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        CATransaction.begin()
        CATransaction.setDisableActions(true)
        pageControl.updateProgress(scrollView: scrollView)
        CATransaction.commit()
    }
}

// MARK: -  自定义小圆点
class CustomPageControl: UIPageControl {

    // MARK: - Properties
    private var currentPageWidth: CGFloat = 15.0 // 当前页的宽度
    private var otherPageWidth: CGFloat = 6.0 // 其他页的宽度
    private var pageHeight: CGFloat = 6.0 // 点的高度
    private var spacing: CGFloat = 8.0 // 点之间的间距
    private var currentProgress: CGFloat = 0.0

    // MARK: - Override Properties
    override var currentPage: Int {
        didSet {
            setNeedsDisplay()
        }
    }

    // MARK: - Methods
    func updateProgress(scrollView: UIScrollView) {
        let width = scrollView.bounds.width
        let offsetX = scrollView.contentOffset.x
        currentProgress = (offsetX - width) / width
        setNeedsDisplay()
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        for view in subviews {
            view.isHidden = true
        }
    }

//    override func draw(_ rect: CGRect) {
//        let totalWidth = CGFloat(numberOfPages - 1) * (otherPageWidth + spacing) + currentPageWidth
//        var startX = (rect.width - totalWidth) / 2
//
//        for i in 0 ..< numberOfPages {
//            var dotWidth = otherPageWidth
//            var dotX = startX
//
//            // 确定当前点和目标点
//            if i == currentPage {
//                // 当前选中的点
//                let progress = abs(currentProgress)
//                dotWidth = currentPageWidth - (currentPageWidth - otherPageWidth) * progress
//            } else if (currentProgress > 0 && i == (currentPage + 1) % numberOfPages) ||
//                (currentProgress < 0 && i == (currentPage - 1 + numberOfPages) % numberOfPages)
//            {
//                // 即将变为选中的点
//                let progress = abs(currentProgress)
//                dotWidth = otherPageWidth + (currentPageWidth - otherPageWidth) * progress
//            }
//
//            // 绘制点
//            let dotRect = CGRect(x: dotX,
//                                 y: (rect.height - pageHeight) / 2,
//                                 width: dotWidth,
//                                 height: pageHeight)
//
//            let path = UIBezierPath(roundedRect: dotRect,
//                                    cornerRadius: pageHeight / 2)
//
//            // 计算颜色过渡
//            if i == currentPage {
//                // 当前点颜色逐渐变淡
//                let progress = abs(currentProgress)
//                let color = blendColors(
//                    currentPageIndicatorTintColor ?? .white,
//                    pageIndicatorTintColor ?? .gray,
//                    progress: progress
//                )
//                color.setFill()
//            } else if (currentProgress > 0 && i == (currentPage + 1) % numberOfPages) ||
//                (currentProgress < 0 && i == (currentPage - 1 + numberOfPages) % numberOfPages)
//            {
//                // 目标点颜色逐渐加深
//                let progress = abs(currentProgress)
//                let color = blendColors(
//                    pageIndicatorTintColor ?? .gray,
//                    currentPageIndicatorTintColor ?? .white,
//                    progress: progress
//                )
//                color.setFill()
//            } else {
//                pageIndicatorTintColor?.setFill()
//            }
//
//            path.fill()
//
//            // 更新下一个点的起始位置
//            startX += dotWidth + spacing
//        }
//    }
    override func draw(_ rect: CGRect) {
        var currentX: CGFloat = 0 // 直接从0开始绘制

        for i in 0 ..< numberOfPages {
            var dotWidth = otherPageWidth

            // 确定当前点和目标点
            if i == currentPage {
                let progress = abs(currentProgress)
                dotWidth = currentPageWidth - (currentPageWidth - otherPageWidth) * progress
            } else if (currentProgress > 0 && i == (currentPage + 1) % numberOfPages) ||
                (currentProgress < 0 && i == (currentPage - 1 + numberOfPages) % numberOfPages)
            {
                let progress = abs(currentProgress)
                dotWidth = otherPageWidth + (currentPageWidth - otherPageWidth) * progress
            }

            // 绘制点
            let dotRect = CGRect(x: currentX,
                                 y: (rect.height - pageHeight) / 2,
                                 width: dotWidth,
                                 height: pageHeight)

            let path = UIBezierPath(roundedRect: dotRect,
                                    cornerRadius: pageHeight / 2)

            // 计算颜色过渡
            if i == currentPage {
                let progress = abs(currentProgress)
                let color = blendColors(
                    currentPageIndicatorTintColor ?? .white,
                    pageIndicatorTintColor ?? .gray,
                    progress: progress
                )
                color.setFill()
            } else if (currentProgress > 0 && i == (currentPage + 1) % numberOfPages) ||
                (currentProgress < 0 && i == (currentPage - 1 + numberOfPages) % numberOfPages)
            {
                let progress = abs(currentProgress)
                let color = blendColors(
                    pageIndicatorTintColor ?? .gray,
                    currentPageIndicatorTintColor ?? .white,
                    progress: progress
                )
                color.setFill()
            } else {
                pageIndicatorTintColor?.setFill()
            }

            path.fill()

            currentX += dotWidth + spacing
        }
    }

    // 添加颜色混合方法
    private func blendColors(_ color1: UIColor, _ color2: UIColor, progress: CGFloat) -> UIColor {
        var r1: CGFloat = 0, g1: CGFloat = 0, b1: CGFloat = 0, a1: CGFloat = 0
        var r2: CGFloat = 0, g2: CGFloat = 0, b2: CGFloat = 0, a2: CGFloat = 0

        color1.getRed(&r1, green: &g1, blue: &b1, alpha: &a1)
        color2.getRed(&r2, green: &g2, blue: &b2, alpha: &a2)

        return UIColor(
            red: r1 + (r2 - r1) * progress,
            green: g1 + (g2 - g1) * progress,
            blue: b1 + (b2 - b1) * progress,
            alpha: a1 + (a2 - a1) * progress
        )
    }

    override var intrinsicContentSize: CGSize {
        // let width = CGFloat(numberOfPages - 1) * (otherPageWidth + spacing) + currentPageWidth
        let width = calculateTotalWidth()
        return CGSize(width: width, height: pageHeight)
    }

    private func calculateTotalWidth() -> CGFloat {
        return CGFloat(numberOfPages - 1) * (otherPageWidth + spacing) + currentPageWidth
    }
}
